import sys
import time
from enum import Enum


def list_insert(prev, next, item):
    prev.next = item
    next.prev = item
    item.next = next
    item.prev = prev


def list_remove(prev, next):
    prev.next = next
    next.prev = prev


def list_split(item):
    list_remove(item.prev, item.next)
    item.next = item
    item.prev = item
    return item


class CycleList(object):
    def __init__(self):
        self.next = self
        self.prev = self

    def is_empty(self):
        return self.next == self

    def append(self, item):
        list_insert(self.prev, self, item)

    def remove(self, item):
        list_split(item)

    def advance(self):
        if self.is_empty():
            return None
        ins_prev = self.next
        ins_next = ins_prev.next
        list_remove(self.prev, self.next)
        list_insert(ins_prev, ins_next, self)
        return self.next

    def curr(self):
        if self.is_empty():
            return None
        return self.next


class MR(object):
    def __init__(self):
        #   next 和 prev 是链表结构
        self.next = self
        self.prev = self
        #   所属仓库的编号
        self.project_id = ""
        #   MR 的编号
        self.mr_id = -1
        #   最新的 commit-id：当MR的 commit-id 变化时，需要重新确定 Reviewer 的人员是谁
        self.last_commit_id = ""
        #   最后检查时间
        self.last_check_time = time.time()


class Repo(object):
    def __init__(self):
        #   仓库挂载的仓库地址
        self.host = ""
        #   仓库路径
        self.path = ""
        #   工程的id（已经转码）
        self.project_id = ""
        #   仓库访问的token
        self.token = ""
        #   操作的用户
        self.user = ""
        #   reviewer 定义文件
        self.reviewer_file = ""
        #   最后同步时间
        self.last_sync_time = time.time()
        #   最新的mr id
        self.latest_mr_id = -1
        #   处于打开状态的mr
        self.mr_queue = CycleList()
        self.mr_map = {}

    def append(self, mr: MR):
        self.mr_queue.append(mr)
        self.mr_map[mr.mr_id] = mr

    def remove(self, mr_id: int):
        mr = self.mr_map[mr_id]
        self.mr_queue.remove(mr)
        del self.mr_map[mr_id]

    def advance(self) -> MR:
        return self.mr_queue.advance()

    def curr(self):
        return self.mr_queue.curr()


class RepoTable(object):
    def __init__(self):
        self._repos = {}

    def get_repo(self, project_id: str) -> Repo:
        return self._repos.get(project_id)


global_repos = RepoTable()


class Task(object):
    """
    Task 定义了一个任务对象，该对象必须实现一个 run 接口
    """

    def run(self):
        pass


class MRAction(Enum):
    #   创建
    OPENED = 0
    #   关闭
    CLOSED = 1
    #   更新
    UPDATED = 2


class TaskMREvent(Task):
    """
    表示该MR发生了变化
    """

    def __init__(self, project_id: str, mr_id: str, action: MRAction):
        self.project_id = project_id
        self.mr_id = mr_id
        self.action = action
        action_handles = {
            MRAction.OPENED: self.HandleOpened,
            MRAction.CLOSED: self.HandleClosed,
            MRAction.UPDATED: self.HandleUpdated,
        }
        self.handle = action_handles[action]

    def run(self):
        self.handle()

    def HandleOpened(self):
        #   查询完成信息，然后追加到
        repo = global_repos.get_repo(self.project_id)
        if repo is None:
            return

        mr = MR()
        #   获取mr的基本信息，
        repo.append(mr)

    def HandleClosed(self):
        repo = global_repos.get_repo(self.project_id)
        if repo is None:
            return
        repo.remove(self.mr_id)

    def HandleUpdated(self):
        #   获取MR的文件列表

        #   获取MR的所有Review人员 -> a

        #   将修改文件列表转换成Review人员列表 -> b

        #   将 b 中不在 a 中的元素找出来
        pass


def main(argv: [str]) -> int:
    pass


if __name__ == '__main__':
    sys.exit(main(sys.argv))
